package io.gitee.kotle.player.ui.view.exo

import android.content.Context
import android.util.AttributeSet
import android.view.Gravity
import android.view.TextureView
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.core.view.updateLayoutParams
import androidx.media3.common.MediaItem
import io.gitee.kotle.player.core.IPlayer
import io.gitee.kotle.player.core.impl.exoplayer.IExoPlayerMode

/**
 * 画面显示布局
 */
open class ExoPlayerTextureView : FrameLayout, IExoPlayerView {
    companion object {
        const val CENTER_INSIDE = 1
        const val CENTER_CROP = 2
        const val FIT_XY = 3
    }

    private var lastVideoFl: Float = 0f

    /**
     * textureView的缩放模式
     */
    var scaleType = CENTER_INSIDE
        set(value) {
            field = value
            updateLayout(lastVideoFl)
        }

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context, attrs, defStyleAttr
    )

    val textureView by lazy {
        TextureView(context).also {
            addView(it, LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
            ).also { lp ->
                lp.gravity = Gravity.CENTER
            })
        }
    }

    override fun needPlayerListener(): Boolean {
        return true
    }

    override fun onPlayerViewConfigCreated(
        player: IPlayer<MediaItem, IExoPlayerMode>, config: ExoPlayerViewConfig<IExoPlayerMode>
    ) {
        super.onPlayerViewConfigCreated(player, config)
        player.attachTextureView(textureView)
    }

    override fun onPlayerViewConfigDestroyed(
        player: IPlayer<MediaItem, IExoPlayerMode>, config: ExoPlayerViewConfig<IExoPlayerMode>
    ) {
        super.onPlayerViewConfigDestroyed(player, config)
    }

    override fun onVideoSizeChange(
        player: IPlayer<MediaItem, IExoPlayerMode>,
        width: Int,
        height: Int,
        unAppliedRotationDegrees: Int,
        pixelWidthHeightRatio: Float
    ) {
        super.onVideoSizeChange(
            player, width, height, unAppliedRotationDegrees, pixelWidthHeightRatio
        )
        updateLayout(width.toFloat() / height)
    }

    private fun updateLayout(videoFl: Float) {
        if (videoFl <= 0f) {
            return
        }
        lastVideoFl = videoFl
        if (width <= 0 || height <= 0) {
            return
        }
        textureView.scaleX = 1f
        textureView.scaleY = 1f
        when (scaleType) {
            CENTER_CROP -> {
                getChildParams(videoFl) { childW, childH, scale ->
                    //居中布局，然后缩放
                    textureView.updateLayoutParams<LayoutParams> {
                        width = childW
                        height = childH
                    }
                    //进行缩放
                    textureView.pivotX = childW / 2f
                    textureView.pivotY = childH / 2f
                    textureView.scaleX = scale
                    textureView.scaleY = scale
                }

            }

            FIT_XY -> {
                textureView.updateLayoutParams<LayoutParams> {
                    width = LayoutParams.MATCH_PARENT
                    height = LayoutParams.MATCH_PARENT
                }
            }

            else -> {
                getChildParams(videoFl) { childW, childH, _ ->
                    textureView.updateLayoutParams<LayoutParams> {
                        width = childW
                        height = childH
                    }
                }
            }
        }
    }

    private fun getChildParams(
        childRatio: Float, block: (Int, Int, Float) -> Unit
    ) {
        val width = this.width - paddingStart - paddingEnd
        val height = this.height - paddingTop - paddingBottom
        val parentRatio = width.toFloat() / height
        if (childRatio <= parentRatio) {
            //child 高度不变
            val childWidth = height * childRatio
            block.invoke(childWidth.toInt(), height, width / childWidth)
        } else {
            //宽度不变
            val childHeight = width / childRatio
            block.invoke(width, childHeight.toInt(), height / childHeight)
        }
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        if (changed) {
            updateLayout(lastVideoFl)
        }
    }
}